package com.hup.utils.commons.exception;

import lombok.AccessLevel;
import lombok.Getter;
import lombok.NoArgsConstructor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * 异常堆栈信息打印工具,
 * 最多打印n个堆栈记录(第一个记录+符合包名的记录)
 * @author hugan
 * @date 2019/8/10
 */
@NoArgsConstructor(access = AccessLevel.PRIVATE)
public class TraceHandler {
    private static final Logger LOGGER = LoggerFactory.getLogger(TraceHandler.class);

    public static final TraceHandler TRACE_HANDLER = new TraceHandler("com.hup", 10);

    /**
     * 包名
     */
    private String packageSt;

    /**
     * 最多打印n个堆栈记录(第一个记录+符合包名的记录)
     */
    @Getter
    private int maxPrintCount;

    public TraceHandler(String packageSt, int maxPrintCount) {
        this.packageSt = packageSt;
        this.maxPrintCount = maxPrintCount;
    }

    public String getTrace(Throwable t) {
        StringBuilder sb = new StringBuilder();
        //org.springframework.web.HttpRequestMethodNotSupportedException: Request method 'GET' not supported
        sb.append("\n").append(t.getClass());
        StackTraceElement[] st = t.getStackTrace();
        int length = st.length;
        if (length == 0) {
            LOGGER.error("getTrace.堆栈长度是0?", t);
        } else {
            //发生错误的当行,必然会打印出来
            //换行后加空格:处理某些情况下view不支持显示\t
            sb.append("\n  \tat ").append(st[0]);

            int printCount = 1;
            for (int i = 1; i < length; i++) {
                //从第2个记录开始过滤
                StackTraceElement te = st[i];
                if (!te.getClassName().startsWith(packageSt)) {
                    continue;
                }
                sb.append("\n  \tat ").append(te);
                printCount++;
                if (printCount >= maxPrintCount) {
                    break;
                }
            }
        }
        return sb.toString();
    }

}
